<?php

namespace Yearnfar\Bundle\CmsBundle\Twig\Extension;

use CG\Core\ClassUtils;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class CmsExtension extends \Twig_Extension
{
    protected $loader;
    protected $controller;

    public function __construct(\Twig_LoaderInterface $loader)
    {
        $this->loader = $loader;
    }

    public function setController($controller)
    {
        $this->controller = $controller;
    }

    /**
     * 注册方法
     * {@inheritdoc}
     */
    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('getUser',  array($this, 'getUser'), array('is_safe' => array('html'))),
            new \Twig_SimpleFunction('getMenu',  array($this, 'getMenu'), array('is_safe' => array('html'))),
        );
    }

    /**
     * 获取用户信息
     * @return mixed
     */
    public function getUser()
    {
        return $this->controller[0]->getUser();
    }

    /**
     * 通过route 获得 path
     * @param $name
     * @param array $parameters
     * @param bool $relative
     * @return mixed
     */
    public function getPath($name, $parameters = array(), $relative = false)
    {
        if ($name=='' || $name=='#'){
            return '#';
        }
        $generator = $this->controller[0]->get('router')->getGenerator();
        return $generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
    }

    /**
     * 获取菜单信息
     * @return array
     */
    public function getMenu()
    {
        $route = $this->controller[0]->get('request')->attributes->get('_route');
        $em    = $this->controller[0]->get('doctrine')->getManager();

        $admin = $this->controller[0]->getUser();//用户权限
        $privilege  = $admin->getPrivilege();//私有权限

        $role  = isset($admin->getRoles()[0]) ? $admin->getRoles()[0] : '';//用户分组
        $group = $em->getRepository('CmsBundle:groups')->findOneBy(['role'=>$role]);
        $gid   = $group ? $group->getPrivilege() : -1;

        $sideMenu = $em->getRepository('CmsBundle:menu')->findBy([], ['pid'=>'ASC', 'id'=>'ASC']);

        $callBack =
            function (&$result, &$open=false, &$valid=false, $pid=0) use (&$callBack, $sideMenu, $route, $privilege, $gid)
            {
                $htm = '';
                foreach ($sideMenu as $om)
                {
                    if ($om->getPid()==$pid) {
                        $_id    = $om->getId();
                        $_open  = false; //是否展开
                        $_valid = false; //是否有权限

                        if (($om->getPower() & 1<<$gid) ||
                            isset($privilege[$_id]) && $privilege[$_id])
                        {
                            if (!$valid) {//子菜单有权限则父菜单必有权限
                                $valid = true;
                            }
                            $_valid = true;
                        }

                        $_valid2 = false;
                        $sub = $callBack($result, $_open, $_valid2, $_id);

                        if (!$_valid && !$_valid2) {
                            continue;
                        }

                        $_route = $om->getRoute();
                        $style  = '';

                        if ($_open || $_route == $route) {
                            array_unshift($result, $om);

                            $style = 'active' . ($_route == $route ? '' : ' open');
                            $open  = true;
                        }

                        $icon = $om->getClass();
                        $name = $om->getName();
                        $path = $this->getPath($_route);

                        if ($pid==0) {
                            $name = '<span class="menu-text">' . $name . '</span>';
                        } elseif ($icon=='') {
                            $icon = 'fa-caret-right';
                        }

                        if ($sub!='') {
                            $htm .=
                                '<li class="'. $style . '">' .
                                '    <a href="'. $path . '" class="dropdown-toggle">' .
                                '        <i class="menu-icon fa ' . $icon .'"></i>' .
                                '        ' . $name .
                                '        <b class="arrow fa fa-angle-down"></b>' .
                                '    </a>' .
                                '    <ul class="submenu nav-show" style="' . ($_open ? 'display:block;' : '') . '">' .
                                '        ' . $sub .
                                '    </ul>'.
                                '</li>';
                        } else {
                            $htm .=
                                '<li class="'  . $style . '">'.
                                '    <a href="'. $path. '">' .
                                '        <i class="menu-icon fa ' . $icon .'"></i>'.
                                '        ' . $name .
                                '    </a>' .
                                '</li>';
                        }
                    }
                }
                return $htm;
            };

        $_nav = [];
        $side = $callBack($_nav);
        $nav  = '';

        foreach ($_nav as $k => $om) {
            $path = $this->getPath($om->getRoute());

            if ($k==0) {
                $nav .= '<li class="active"><a href="' . $path . '">' . $om->getName() . '</a></li>';
            } else {
                $nav .= '<li><a href="' . $path . '">'.$om->getName().'</a></li>';
            }
        }

        return ['nav'=>$nav, 'side'=>$side, 'current'=>$om];
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'yearnfar.cms';
    }
}
